home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / CardLayout.java < prev    next >
Text File  |  1998-09-22  |  15KB  |  448 lines

  1. /*
  2.  * @(#)CardLayout.java    1.22 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.awt;
  16.  
  17. import java.util.Hashtable;
  18. import java.util.Enumeration;
  19.  
  20. /**
  21.  * A <code>CardLayout</code> object is a layout manager for a 
  22.  * container. It treats each component in the container as a card.
  23.  * Only one card is visible at a time, and the container acts as
  24.  * a stack of cards.  
  25.  * <p>
  26.  * The ordering of cards is determined by the container's own internal
  27.  * ordering of its component objects. <code>CardLayout</code> 
  28.  * defines a set of methods that allow an application to flip 
  29.  * through these cards sequentially, or to show a specified card.
  30.  * The <A HREF="#addLayoutComponent"><code>addLayoutComponent</code></A> 
  31.  * method can be used to associate a string identifier with a given card
  32.  * for fast random access.
  33.  *
  34.  * @version     1.22 07/01/98
  35.  * @author     Arthur van Hoff
  36.  * @see         java.awt.Container
  37.  * @since       JDK1.0
  38.  */
  39.  
  40. public class CardLayout implements LayoutManager2,
  41.                    java.io.Serializable {
  42.     Hashtable tab = new Hashtable();
  43.     int hgap;
  44.     int vgap;
  45.  
  46.     /**
  47.      * Creates a new card layout with gaps of size zero.
  48.      * @since  JDK1.0
  49.      */
  50.     public CardLayout() {
  51.     this(0, 0);
  52.     }
  53.  
  54.     /**
  55.      * Creates a new card layout with the specified horizontal and 
  56.      * vertical gaps. The horizontal gaps are placed at the left and 
  57.      * right edges. The vertical gaps are placed at the top and bottom 
  58.      * edges. 
  59.      * @param     hgap   the horizontal gap.
  60.      * @param     vgap   the vertical gap.
  61.      * @since     JDK1.0
  62.      */
  63.     public CardLayout(int hgap, int vgap) {
  64.     this.hgap = hgap;
  65.     this.vgap = vgap;
  66.     }
  67.  
  68.     /**
  69.      * Gets the horizontal gap between components.
  70.      * @return    the horizontal gap between components.
  71.      * @see       java.awt.CardLayout#setHgap(int)
  72.      * @see       java.awt.CardLayout#getVgap()
  73.      * @since     JDK1.1
  74.      */
  75.     public int getHgap() {
  76.     return hgap;
  77.     }
  78.     
  79.     /**
  80.      * Sets the horizontal gap between components.
  81.      * @param hgap the horizontal gap between components.
  82.      * @see       java.awt.CardLayout#getHgap()
  83.      * @see       java.awt.CardLayout#setVgap(int)
  84.      * @since     JDK1.1
  85.      */
  86.     public void setHgap(int hgap) {
  87.     this.hgap = hgap;
  88.     }
  89.     
  90.     /**
  91.      * Gets the vertical gap between components.
  92.      * @return the vertical gap between components.
  93.      * @see       java.awt.CardLayout#setVgap(int)
  94.      * @see       java.awt.CardLayout#getHgap()
  95.      */
  96.     public int getVgap() {
  97.     return vgap;
  98.     }
  99.     
  100.     /**
  101.      * Sets the vertical gap between components.
  102.      * @param     vgap the vertical gap between components.
  103.      * @see       java.awt.CardLayout#getVgap()
  104.      * @see       java.awt.CardLayout#setHgap(int)
  105.      * @since     JDK1.1
  106.      */
  107.     public void setVgap(int vgap) {
  108.     this.vgap = vgap;
  109.     }
  110.  
  111.     /**
  112.      * Adds the specified component to this card layout's internal
  113.      * table of names. The object specified by <code>constraints</code>  
  114.      * must be a string. The card layout stores this string as a key-value
  115.      * pair that can be used for random access to a particular card.
  116.      * By calling the <code>show</code> method, an application can  
  117.      * display the component with the specified name. 
  118.      * @param     comp          the component to be added.
  119.      * @param     constraints   a tag that identifies a particular 
  120.      *                                        card in the layout.
  121.      * @see       java.awt.CardLayout#show(java.awt.Container, java.lang.String)
  122.      * @exception  IllegalArgumentException  if the constraint is not a string.
  123.      * @since     JDK1.0
  124.      */
  125.     public void addLayoutComponent(Component comp, Object constraints) {
  126.       synchronized (comp.getTreeLock()) {
  127.     if (constraints instanceof String) {
  128.         addLayoutComponent((String)constraints, comp);
  129.     } else {
  130.         throw new IllegalArgumentException("cannot add to layout: constraint must be a string");
  131.     }
  132.       }
  133.     }
  134.  
  135.     /**
  136.      * @deprecated   replaced by 
  137.      *      <code>addLayoutComponent(Component, Object)</code>.
  138.      */
  139.     public void addLayoutComponent(String name, Component comp) {
  140.       synchronized (comp.getTreeLock()) {
  141.     if (tab.size() > 0) {
  142.         comp.hide();
  143.     }
  144.     tab.put(name, comp);
  145.       }
  146.     }
  147.  
  148.     /**
  149.      * Removes the specified component from the layout.
  150.      * @param   comp   the component to be removed.
  151.      * @see     java.awt.Container#remove(java.awt.Component)
  152.      * @see     java.awt.Container#removeAll()
  153.      * @since   JDK1.0
  154.      */
  155.     public void removeLayoutComponent(Component comp) {
  156.       synchronized (comp.getTreeLock()) {
  157.     for (Enumeration e = tab.keys() ; e.hasMoreElements() ; ) {
  158.         String key = (String)e.nextElement();
  159.         if (tab.get(key) == comp) {
  160.         tab.remove(key);
  161.         return;
  162.         }
  163.     }
  164.       }
  165.     }
  166.  
  167.     /** 
  168.      * Determines the preferred size of the container argument using 
  169.      * this card layout.
  170.      * @param   parent the name of the parent container.
  171.      * @return  the preferred dimensions to lay out the subcomponents 
  172.      *                of the specified container.
  173.      * @see     java.awt.Container#getPreferredSize
  174.      * @see     java.awt.CardLayout#minimumLayoutSize
  175.      * @since   JDK1.0
  176.      */
  177.     public Dimension preferredLayoutSize(Container parent) {
  178.       synchronized (parent.getTreeLock()) {
  179.     Insets insets = parent.getInsets();
  180.     int ncomponents = parent.getComponentCount();
  181.     int w = 0;
  182.     int h = 0;
  183.  
  184.     for (int i = 0 ; i < ncomponents ; i++) {
  185.         Component comp = parent.getComponent(i);
  186.         Dimension d = comp.getPreferredSize();
  187.         if (d.width > w) {
  188.         w = d.width;
  189.         }
  190.         if (d.height > h) {
  191.         h = d.height;
  192.         }
  193.     }
  194.     return new Dimension(insets.left + insets.right + w + hgap*2, 
  195.                  insets.top + insets.bottom + h + vgap*2);
  196.       }
  197.     }
  198.  
  199.     /** 
  200.      * Calculates the minimum size for the specified panel.
  201.      * @param     parent the name of the parent container 
  202.      *                in which to do the layout.
  203.      * @return    the minimum dimensions required to lay out the 
  204.      *                subcomponents of the specified container.
  205.      * @see       java.awt.Container#doLayout
  206.      * @see       java.awt.CardLayout#preferredLayoutSize 
  207.      * @since     JDK1.0
  208.      */
  209.     public Dimension minimumLayoutSize(Container parent) {
  210.       synchronized (parent.getTreeLock()) {
  211.     Insets insets = parent.getInsets();
  212.     int ncomponents = parent.getComponentCount();
  213.     int w = 0;
  214.     int h = 0;
  215.  
  216.     for (int i = 0 ; i < ncomponents ; i++) {
  217.         Component comp = parent.getComponent(i);
  218.         Dimension d = comp.getMinimumSize();
  219.         if (d.width > w) {
  220.         w = d.width;
  221.         }
  222.         if (d.height > h) {
  223.         h = d.height;
  224.         }
  225.     }
  226.     return new Dimension(insets.left + insets.right + w + hgap*2, 
  227.                  insets.top + insets.bottom + h + vgap*2);
  228.       }
  229.     }
  230.  
  231.     /**
  232.      * Returns the maximum dimensions for this layout given the components
  233.      * in the specified target container.
  234.      * @param target the component which needs to be laid out
  235.      * @see Container
  236.      * @see #minimumLayoutSize
  237.      * @see #preferredLayoutSize
  238.      */
  239.     public Dimension maximumLayoutSize(Container target) {
  240.     return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  241.     }
  242.  
  243.     /**
  244.      * Returns the alignment along the x axis.  This specifies how
  245.      * the component would like to be aligned relative to other 
  246.      * components.  The value should be a number between 0 and 1
  247.      * where 0 represents alignment along the origin, 1 is aligned
  248.      * the furthest away from the origin, 0.5 is centered, etc.
  249.      */
  250.     public float getLayoutAlignmentX(Container parent) {
  251.     return 0.5f;
  252.     }
  253.  
  254.     /**
  255.      * Returns the alignment along the y axis.  This specifies how
  256.      * the component would like to be aligned relative to other 
  257.      * components.  The value should be a number between 0 and 1
  258.      * where 0 represents alignment along the origin, 1 is aligned
  259.      * the furthest away from the origin, 0.5 is centered, etc.
  260.      */
  261.     public float getLayoutAlignmentY(Container parent) {
  262.     return 0.5f;
  263.     }
  264.  
  265.     /**
  266.      * Invalidates the layout, indicating that if the layout manager
  267.      * has cached information it should be discarded.
  268.      */
  269.     public void invalidateLayout(Container target) {
  270.     }
  271.                       
  272.     /** 
  273.      * Lays out the specified container using this card layout. 
  274.      * <p>
  275.      * Each component in the <code>parent</code> container is reshaped 
  276.      * to be the size of the container, minus space for surrounding 
  277.      * insets, horizontal gaps, and vertical gaps. 
  278.      * 
  279.      * @param     parent the name of the parent container 
  280.      *                             in which to do the layout. 
  281.      * @see       java.awt.Container#doLayout
  282.      * @since     JDK1.0 
  283.      */
  284.     public void layoutContainer(Container parent) {
  285.       synchronized (parent.getTreeLock()) {
  286.     Insets insets = parent.getInsets();
  287.     int ncomponents = parent.getComponentCount();
  288.     for (int i = 0 ; i < ncomponents ; i++) {
  289.         Component comp = parent.getComponent(i);
  290.         if (comp.visible) {
  291.         comp.setBounds(hgap + insets.left, vgap + insets.top, 
  292.                    parent.width - (hgap*2 + insets.left + insets.right), 
  293.                    parent.height - (vgap*2 + insets.top + insets.bottom));
  294.         }
  295.     }
  296.       }
  297.     }
  298.  
  299.     /**
  300.      * Make sure that the Container really has a CardLayout installed.
  301.      * Otherwise havoc can ensue!
  302.      */
  303.     void checkLayout(Container parent) {
  304.     if (parent.getLayout() != this) {
  305.         throw new IllegalArgumentException("wrong parent for CardLayout");
  306.     }
  307.     }
  308.  
  309.     /**
  310.      * Flips to the first card of the container. 
  311.      * @param     parent   the name of the parent container 
  312.      *                          in which to do the layout.
  313.      * @see       java.awt.CardLayout#last
  314.      * @since     JDK1.0
  315.      */
  316.     public void first(Container parent) {
  317.     synchronized (parent.getTreeLock()) {
  318.         checkLayout(parent);
  319.         int ncomponents = parent.getComponentCount();
  320.         for (int i = 0 ; i < ncomponents ; i++) {
  321.         Component comp = parent.getComponent(i);
  322.         if (comp.visible) {
  323.             comp.hide();
  324.             comp = parent.getComponent(0);
  325.             comp.show();
  326.             parent.validate();
  327.             return;
  328.         }
  329.         }
  330.     }
  331.     }
  332.  
  333.     /**
  334.      * Flips to the next card of the specified container. If the 
  335.      * currently visible card is the last one, this method flips to the 
  336.      * first card in the layout. 
  337.      * @param     parent   the name of the parent container 
  338.      *                          in which to do the layout.
  339.      * @see       java.awt.CardLayout#previous
  340.      * @since     JDK1.0
  341.      */
  342.     public void next(Container parent) {
  343.     synchronized (parent.getTreeLock()) {
  344.         checkLayout(parent);
  345.         int ncomponents = parent.getComponentCount();
  346.         for (int i = 0 ; i < ncomponents ; i++) {
  347.         Component comp = parent.getComponent(i);
  348.         if (comp.visible) {
  349.             comp.hide();
  350.             comp = parent.getComponent((i + 1 < ncomponents) ? i+1 : 0);
  351.             comp.show();
  352.             parent.validate();
  353.             return;
  354.         }
  355.         }
  356.     }
  357.     }
  358.  
  359.     /**
  360.      * Flips to the previous card of the specified container. If the 
  361.      * currently visible card is the first one, this method flips to the 
  362.      * last card in the layout. 
  363.      * @param     parent   the name of the parent container 
  364.      *                          in which to do the layout.
  365.      * @see       java.awt.CardLayout#next
  366.      * @since     JDK1.0
  367.      */
  368.     public void previous(Container parent) {
  369.     synchronized (parent.getTreeLock()) {
  370.         checkLayout(parent);
  371.         int ncomponents = parent.getComponentCount();
  372.         for (int i = 0 ; i < ncomponents ; i++) {
  373.         Component comp = parent.getComponent(i);
  374.         if (comp.visible) {
  375.             comp.hide();
  376.             comp = parent.getComponent((i > 0) ? i-1 : ncomponents-1);
  377.             comp.show();
  378.             parent.validate();
  379.             return;
  380.         }
  381.         }
  382.     }
  383.     }
  384.  
  385.     /**
  386.      * Flips to the last card of the container. 
  387.      * @param     parent   the name of the parent container 
  388.      *                          in which to do the layout.
  389.      * @see       java.awt.CardLayout#first
  390.      * @since     JDK1.0
  391.      */
  392.     public void last(Container parent) {
  393.     synchronized (parent.getTreeLock()) {
  394.         checkLayout(parent);
  395.         int ncomponents = parent.getComponentCount();
  396.         for (int i = 0 ; i < ncomponents ; i++) {
  397.         Component comp = parent.getComponent(i);
  398.         if (comp.visible) {
  399.             comp.hide();
  400.             comp = parent.getComponent(ncomponents - 1);
  401.             comp.show();
  402.             parent.validate();
  403.             return;
  404.         }
  405.         }
  406.     }
  407.     }
  408.  
  409.     /**
  410.      * Flips to the component that was added to this layout with the  
  411.      * specified <code>name</code>, using <code>addLayoutComponent</code>.  
  412.      * If no such component exists, then nothing happens. 
  413.      * @param     parent   the name of the parent container 
  414.      *                     in which to do the layout.
  415.      * @param     name     the component name.
  416.      * @see       java.awt.CardLayout#addLayoutComponent(java.awt.Component, java.lang.Object)
  417.      * @since     JDK1.0
  418.      */
  419.     public void show(Container parent, String name) {
  420.     synchronized (parent.getTreeLock()) {
  421.         checkLayout(parent);
  422.         Component next = (Component)tab.get(name);
  423.         if ((next != null) && !next.visible){
  424.         int ncomponents = parent.getComponentCount();
  425.         for (int i = 0 ; i < ncomponents ; i++) {
  426.             Component comp = parent.getComponent(i);
  427.             if (comp.visible) {
  428.             comp.hide();
  429.             break;
  430.             }
  431.         }
  432.         next.show();
  433.         parent.validate();
  434.         }
  435.     }
  436.     }
  437.     
  438.     /**
  439.      * Returns a string representation of the state of this card layout.
  440.      * @return    a string representation of this card layout.
  441.      * @since     JDK1.0
  442.      */
  443.     public String toString() {
  444.     return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
  445.     }
  446.  
  447. }
  448.